package cn.com.bluemoon.daps.standard.service.impl;

import cn.com.bluemoon.daps.common.domain.BaseModel;
import cn.com.bluemoon.daps.common.domain.UserInfoHolder;
import cn.com.bluemoon.daps.common.enums.BmStatus;
import cn.com.bluemoon.daps.common.enums.StandardAuditStatus;
import cn.com.bluemoon.daps.common.exception.DapException;
import cn.com.bluemoon.daps.standard.entity.DapStandardAuditVersionMain;
import cn.com.bluemoon.daps.standard.service.DapStandardAuditService;
import cn.com.bluemoon.daps.standard.service.DapStandardAuditVersionMainService;
import cn.com.bluemoon.daps.standard.vo.StandardDataModifyVo;
import cn.com.bluemoon.daps.standard.vo.StandardListSearchVo;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.validation.constraints.NotNull;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.function.Consumer;

/**
 * @author Jarod.Kong
 * @date 2020/8/10 17:28
 */
@Service
@Transactional(rollbackFor = {DapException.class, RuntimeException.class})
@Slf4j
public class DapStandardAuditServiceImpl implements DapStandardAuditService {

    @Resource
    private DapStandardAuditVersionMainService auditVersionMainService;

    /**
     * @since 2020年10月13日 通过 增加变更类型入参（由于删除操作走流程变更，当确认通过时要对标准进行删除
     *@param auditId 审批流程
     */
    @Override
    public void passAudit(@NotNull(message = "流程id不可为空") String... auditIds) {
        passOrUnPassAudit(auditId -> {
            DapStandardAuditVersionMain auditVersionMain = auditVersionMainService.getByIdAsset(auditId, "获取审批流程失败");
            auditVersionMainService.auditChangeStatusByAuditId(auditId, StandardAuditStatus.通过, auditVersionMain.getModifyType());
        }, auditIds);
    }

    /**
     *  针对通过和不通过的抽取
     * @param auditIdConsumer 业务实现
     * @param auditId 审批id
     */
    private void passOrUnPassAudit(Consumer<String> auditIdConsumer, String... auditId){
        if (auditId != null) {
            Arrays.stream(auditId).forEach(auditIdConsumer);
        }
    }

    /**
     * 获取审批列表数据
     * 获取审批列表数据-树形结构
     *
     * @param standardListSearchVo 查询条件 非空
     * @return
     */
    @Override
    public IPage<StandardDataModifyVo> auditList(StandardListSearchVo<?> standardListSearchVo) {
        return Boolean.FALSE.equals(standardListSearchVo.getTreePage()) ?
                auditVersionMainService.modifyOrAuditListOfStandard(standardListSearchVo, Boolean.TRUE) :
                auditVersionMainService.modifyOrAuditLogicPageOfStandard(standardListSearchVo, Boolean.TRUE);
    }

    @Override
    public void unpassAudit(String... auditIds) {
        passOrUnPassAudit(auditId -> {
            auditVersionMainService.getByIdAsset(auditId, "获取审批流程失败");
            auditVersionMainService.auditChangeStatusByAuditId(auditId, StandardAuditStatus.不通过, null);
        }, auditIds);

    }

    @Override
    public List<StandardDataModifyVo> viewVersions(String standardUniqueId, boolean treeData) {
        // 调用 cn.com.bluemoon.dap.service.impl.DapStandardAuditServiceImpl.auditList 前构造
        // cn.com.bluemoon.dap.cn.com.bluemoon.common.webhook.controller.vo.StandardListSearchVo
        StandardListSearchVo<?> searchVo = new StandardListSearchVo<>();
        searchVo.setPageSize(Integer.MAX_VALUE);
        searchVo.setCurrent(1);
        LambdaQueryWrapper<DapStandardAuditVersionMain> where = Wrappers.<DapStandardAuditVersionMain>lambdaQuery()
                .eq(DapStandardAuditVersionMain::getStandardUniqueId, standardUniqueId).eq(BaseModel::getBmStatus, BmStatus.ON)
                .last(" limit 1 ");
        Integer standardType = Optional.ofNullable(auditVersionMainService.getOne(where)).map(DapStandardAuditVersionMain::getStandardType).orElse(0);
        searchVo.setStandardType(standardType);
        searchVo.setStandardUniqueId(standardUniqueId);
        searchVo.setTreePage(treeData);
        IPage<StandardDataModifyVo> page = auditList(searchVo);
        return page.getRecords();
    }

    @Override
    public void saveStandardVersion(List<String> auditIds, String modifyDesc, UserInfoHolder.UserInfo userInfo) {
        auditVersionMainService.saveStandardVersion(auditIds, modifyDesc, userInfo);
    }
}
